from xmlrpclib import ServerProxy,Fault,ProtocolError
from Portal import Portal
from Exception_ import FgsException
from Cache import Cache
import os, ConfigParser

class PortalDesc(object):
    def __init__(self, client, **kwargs):
        self.client = client
        self._cache = self.client.cache
        for k,v in kwargs.items():
            if k.startswith("portal_"):
                k = k[7:]
            self.__dict__[k] = v

    def __getattr__(self, name):
        if name == 'logo_path':
            return self._get_logo_path()
        else:
            raise AttributeError

    def _get_logo_path(self):
        if self.icon_hash == '':
            return False

        # Ask the cache if it has the right logo
        logo = self._cache.retrieve_file_path(self.icon_hash)
        if logo:
            return logo

        # If the cache doesn't have it, retrieve it from the portal.
        try:
            p = ServerProxy(self.client.master_uri)
            logo_data = p.portal.getlogo(self.icon_hash)
        except Fault,f:
            raise FgsException("XmlRPC call faulted: %s" % f.faultString)
        except ProtocolError, p:
            raise FgsException("Transport error during XmlRpc call on %s: %s" % (p.errmsg, p.url))

        from base64 import decodestring
        logo_data = decodestring(logo_data['logo'])

        if self._cache.cache_enabled():
            # Store the data in cache and return it
            self._cache.store_file(logo_data, self.icon_hash)
            return self._cache.retrieve_file_path(self.icon_hash)
        else:
            # Fallback when no cache is available.
            from os.path import join
            from os import getcwd
            file_path = join(getcwd(), self.icon_hash)
            f = file(file_path, 'w')
            f.write(logo_data)
            f.close()
            return file_path


class Client(object):
    master_uri = "http://freegs.net/remote/RPC2"

    def __init__(self, portal=None, user=None, passwd=None, cache_root=None, auto_connect=False):
        self.cache = Cache(cache_root)

        self.config_filename = os.path.join(os.path.expanduser(u'~'), '.fgs', 'fgs-client.conf')
        self.config = ConfigParser.ConfigParser()
        self.have_config = False
        self.config.read([self.config_filename])
        if self.config.has_section('account'):
            self.have_config = True

        self.auto_connect = auto_connect
        if portal and user and passwd:
            self.get_portal(portal, user, passwd)
        else:
            self.portal_uri = None
            self.portal = None
            self.user = None

        if self.have_config:
            self.portal_uri = self.config.get('account', 'portal')
            self.user = self.config.get('account', 'login')
            self.passwd = self.config.get('account', 'password')
            self.auto_connect = self.config.get('account', 'auto_connect')

    def get_portal(self, portal_uri, user, passwd):
        self.portal_uri = portal_uri
        self.portal = Portal(self.portal_uri, user, passwd, self.cache)
        self.user = self.portal.user
        self.passwd = passwd

    def disconnect(self):
        self.portal_uri = None
        self.portal = None
        self.user = None

    def save_config(self):
        if not self.config.has_section('account'):
			self.config.add_section('account')
        self.config.set('account', 'portal', self.portal_uri)
        self.config.set('account', 'login', self.user)
        self.config.set('account', 'password', self.passwd)
        self.config.set('account', 'auto_connect', self.auto_connect)
        self.config.write(open(self.config_filename, 'w'));

    def __getattr__(self, name):
        if name == 'portals':
            self.__dict__['portals'] = self._get_portals()
            return self.__dict__['portals']
        else:
            raise AttributeError

    def clear(self):
        del self.__dict__['portals']

    def _get_commands(self):
        try:
            commands_list = ServerProxy(self.master_uri).games.list()
        except Fault, f:
            raise FgsException('XmlRpc call faulted: %s' % f.faultString)
        except ProtocolError, p:
            raise FgsException('Transport error during XmlRpc call on %s: %s' % (p.errmsg, p.url))

        commands = []
        for p in commands_list:
            commands.append(p)

        return dict([(x, commands[x]) for x in range(len(commands))])

    def _get_portals(self):
        try:
            portal_list = ServerProxy(self.master_uri).portal.list()
        except Fault, f:
            raise FgsException('XmlRpc call faulted: %s' % f.faultString)
        except ProtocolError, p:
            raise FgsException('Transport error during XmlRpc call on %s: %s' % (p.errmsg, p.url))

        portals = []
        for p in portal_list:
            portals.append(PortalDesc(self, **p))

        return dict([(x, portals[x]) for x in range(len(portals))])
